/*
 * Scheduler.java
 *
 * Created on September 14, 2006, 9:09 PM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */
package smfbackup.run;

import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;
import org.apache.log4j.Logger;
import smfbackup.MainWindow;
import smfbackup.conf.Configuration;
import smfbackup.conf.Forum;
import smfbackup.http.SMFConnection;
import smfbackup.http.SMFSignal;

/**
 * Scheduler takes care of running the forums connections.
 *
 * @author Iulian
 */
public class Scheduler extends Manageable {

    private static Logger log = Logger.getLogger(Scheduler.class);
    Hashtable<Forum, SMFConnection> threads;
    MainWindow mw;

    /** Creates a new instance of Scheduler */
    public Scheduler(MainWindow mw) {
        super();
        this.mw = mw;
        threads = new Hashtable<Forum, SMFConnection>();
    }

    /*
     * Receives a list of forums and will run each backup in separate threads
     */
    public void doJob() {
        reloadConfig();
    }

    /*
     * Shuts down the scheduler which ends all the forum connections too
     */
    public void shutdown() {
        super.shutdown();

        Enumeration e = threads.keys();
        for (; e.hasMoreElements();) {
            Forum f = (Forum) e.nextElement();

            removeForum(f);
        }
    }

    /*
     * Stops active downloads of the current forum but does not end the thread
     */
    public void stopForum(Forum f) {
        SMFConnection conn = (SMFConnection) threads.get(f);

        if (conn != null) {
            conn.signal(SMFSignal.ABORT_DOWNLOAD);
        }
    }

    /*
     * Interrups the sleep of the current forum and starts the download
     */
    public void runForum(Forum f) {
        SMFConnection conn = (SMFConnection) threads.get(f);

        if (conn != null) {
            conn.signal(SMFSignal.RUN_FORCED_BACKUP);
        }
    }

    /*
     * Adds a forum to the scheduler and starts up a connection with that forum
     */
    public void addForum(Forum f) {
        // remove it if it exists
        removeForum(f);

        // start new
        SMFConnection conn = new SMFConnection(f);
        threads.put(f, conn);

        f.updateStatus("About to start thread.");
        conn.setPriority(Thread.MIN_PRIORITY);
        conn.start();
    }

    /*
     * Removes a forum from the scheduler (forum's connection too)
     */
    public void removeForum(Forum f) {
        if (threads.containsKey(f)) {
            SMFConnection conn = (SMFConnection) threads.get(f);
            f.updateStatus("Forum thread is running. Shutting it down.");
            conn.shutdown();
            try {
                conn.join();
            } catch (Exception e) {
                f.updateStatus(e.getMessage());
            }

            threads.remove(f);
            f.updateStatus("Forum thread shut down.");
        }
    }

    /*
     * Stops all forum connections
     */
    public void stopAllForums() {
        Enumeration e = threads.keys();

        for (; e.hasMoreElements();) {
            SMFConnection conn = (SMFConnection) threads.get(e.nextElement());
            conn.signal(SMFSignal.ABORT_DOWNLOAD);
        }
    }

    /**
     * Reload the configuration
     */
    public void reloadConfig() {
        Vector v = Configuration.getForumsDefined();

        for (int i = 0; i < v.size(); i++) {
            Forum f = (Forum) v.elementAt(i);
            if (threads.containsKey(f)) {
                SMFConnection conn = threads.get(f);
                conn.signal(SMFSignal.RELOAD_CONFIG);
            } else {
                addForum(f);
            }
        }
    }
}
